﻿using PhotoGallery.Data.Entity;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;

namespace PhotoGallery.Data.Repository
{
    public class PublicAlbumRepository : BaseRepository
    {
        string fileName;
        string path;
        XDocument doc;
        List<PublicAlbum> albums = new List<PublicAlbum>();

        public PublicAlbumRepository()
        {
            path = BasePath + Settings.UploadsFolder;
            fileName = path + "PublicAlbumsData.xml";
            LoadData(fileName);            
        }

        public IEnumerable<PublicAlbum> Get(bool IsAuthenticated)
        {
            if (IsAuthenticated)
            {
                return albums;
            }
            else
            {
                return albums.Where(x => x.Shared == SharedAlbum.Public);
            }
        }

        public PublicAlbum Get(int id)
        {
            return albums.FirstOrDefault(a => a.ID == id); 
        }

        public PublicAlbum GetByOwner(string owner, string folderName)
        {
            return albums.FirstOrDefault(a => a.Owner == owner && a.FolderName == folderName);
        }

        public int Create(PublicAlbum album)
        {
            // add album
            album.ID = GetMaxValue()+1;
            album.CreateDate = DateTime.UtcNow;
            albums.Add(album);

            //// Put album thumbnail
            //if (file != null)
            //{
            //    album.FileName = "album"+album.ID.ToString() + Path.GetExtension(file.FileName);
            //    file.SaveAs(path + album.FileName);
            //}

            XElement xml = new XElement("albums",
            from i in albums
            orderby album.ID
            select new XElement("album",
                      new XElement("id", i.ID),
                      new XElement("title", i.Title),
                      new XElement("FolderName", i.FolderName),
                      new XElement("filename", i.FileName),
                      new XElement("created_date", ConvertDate(i.CreateDate)),
                      new XElement("owner", i.Owner),
                      new XElement("shared", i.Shared)
                      )
            );

            // finaly 
            XDocument doc = new XDocument(xml);
            doc.Save(fileName);

            return album.ID;
        }

        public void Update(PublicAlbum album)
        {
            //if (file != null)
            //{
            //    album.FileName = file.FileName;
            //    file.SaveAs(path + album.FileName);
            //}

            XElement node = doc.Root.Elements("album").Where(i => (int)i.Element("id") == album.ID).FirstOrDefault();

            node.SetElementValue("id", album.ID);
            node.SetElementValue("title", album.Title ?? "");
            node.SetElementValue("filename", album.FileName ?? "");
            node.SetElementValue("created_date", ConvertDate(album.CreateDate));
            node.SetElementValue("shared", (int)album.Shared);
            
            doc.Save(fileName);
        }

        public void Delete(int id)
        {
            PublicAlbum album = albums.FirstOrDefault(a => a.ID == id);
            
            doc.Root.Elements("album").Where(i => (int)i.Element("id") == id).Remove();
            doc.Save(fileName);

            string currentDirectory = path + "Images\\";// TODO + getAlbumFolder(album);
            if (System.IO.Directory.Exists(currentDirectory))
            {
                int fileCount = System.IO.Directory.GetFiles(currentDirectory).Length;
                if (fileCount < 3)
                {
                    System.IO.Directory.Delete(currentDirectory, true);
                    doc.Root.Elements("album").Where(i => (int)i.Element("id") == id).Remove();
                    doc.Save(fileName);
                }
            }
        }

        #region privateMethods

        private int GetMaxValue()
        {
            int count = doc.Descendants("album").Count();
            if (count > 0)
            {
                var maxID = (from prod in doc.Descendants("album")
                             select
                             (
                                         int.Parse(prod.Element("id").Value)
                             )).Max();

                return maxID;
            }
            else
            {
                return 0;
            }
        }

        private void LoadData(string fileName)
        {
            // TODO
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            //----------------------------
            if (!File.Exists(fileName))
            {
                doc =
                  new XDocument(
                    new XElement("albums")
                    );
                doc.Save(fileName);
            }
            else
            {
                doc = XDocument.Load(fileName);
            }
            int count = doc.Descendants("album").Count();
            if (count > 0)
            {

                var q = from album in doc.Descendants("album")
                        select new PublicAlbum(
                                          Convert.ToInt32(album.Element("id").Value),
                                          album.Element("title").Value,
                                          album.Element("FolderName").Value,
                                          album.Element("filename").Value,
                                          ConvertDate(album.Element("created_date").Value),
                                          UploadsUrl + album.Element("owner").Value + "/" + album.Element("filename").Value,
                                          Owner = album.Element("owner").Value,
                                          (SharedAlbum)Enum.Parse(typeof(SharedAlbum), album.Element("shared").Value),
                                          path + album.Element("owner").Value + "\\" + album.Element("filename").Value
                                          );
                albums.AddRange(q.OrderByDescending(x => x.ID).ToList<PublicAlbum>());
            }
        }

        #endregion
    }
}